package Frogger;

//Importacao de Bibliotecas
import java.awt.*;
import java.awt.image.*;

public class GerenciadorImagem extends Thread{
    
    /** INICIO da Criacao do Visual do Lago */
    private int coordenadasXLago[] = {20, 60, 60, 100, 100, 140, 140, 180, 180, 220, 220, 260, 260, 300, 300, 340, 340, 380,  380,  20, 20};
    private int coordenadasYLago[] = {70, 70, 90, 90, 70,  70,  90,  90,  70,  70,  90,  90,  70,  70,  90,  90,  70,  70,  210, 210, 70};
    private Polygon lago = new Polygon(coordenadasXLago, coordenadasYLago, 21);
    /** FIM da Criacao do Visual do Lago */
    
    // Declaracao de Objetos
    private VolatileImage imagemFundo;
    private Graphics graficoEstrategia;
    private BufferStrategy memoriaEstrategia;
    private GraphicsConfiguration graficoConfiguracao;
    
    /** Objetos do Senario */
    private Objetos objetos[];
    
    /** Declaracao das Threads */
    private Frogger oFrogger;
    
    /** Variavel que Indica se o Sapo ando */
    private boolean movimentoSapo = false;
    
    /** Variavel para a manipulacao do tempo de Espera da Thread */
    private long tempoEspera = 1000, tempoEstimadoSistema, tempoEsperaTotal = 1000;
    
    /** Variavel que indica qual eh o nivel de Dificuldade corrente */
    private int levelJogo = 1;
    
    /** Variavel que indica o total de vidas Restantes */
    private int vidas = 3;
    
    /** Variavel que indica o tempo Estimado para o Retorno Depois de Morto */
    private long tempoSapoMorto;
    
    /** Variavel que indica o Tetal de Objetivos concluidos */
    private int totalSmile = 0;
    
    /** Variavel que Indica a Localizacao dos Smiles */
    private Rectangle[] retanguloSmile;
    
    /** INICIO Carregando as imagens */
        public Image Sapo01 = Toolkit.getDefaultToolkit().getImage("Imagens/Sapo01.jpg");
        public Image Sapo02 = Toolkit.getDefaultToolkit().getImage("Imagens/Sapo02.jpg");
        public Image Sapo03 = Toolkit.getDefaultToolkit().getImage("Imagens/Sapo03.jpg");
        public Image Sapo04 = Toolkit.getDefaultToolkit().getImage("Imagens/Sapo04.jpg");
        public Image SapoMorto = Toolkit.getDefaultToolkit().getImage("Imagens/SapoMorto.gif");
        public Image Caminhao01 = Toolkit.getDefaultToolkit().getImage("Imagens/Caminhao01.jpg");
        public Image Caminhao02 = Toolkit.getDefaultToolkit().getImage("Imagens/Caminhao02.jpg");
        public Image Caminhao03 = Toolkit.getDefaultToolkit().getImage("Imagens/Caminhao03.jpg");
        public Image CarroAzulD = Toolkit.getDefaultToolkit().getImage("Imagens/CarroAzulD.jpg");
        public Image CarroAzulE = Toolkit.getDefaultToolkit().getImage("Imagens/CarroAzulE.jpg");
        public Image CarroBrancoD = Toolkit.getDefaultToolkit().getImage("Imagens/CarroBrancoD.jpg");
        public Image CarroBrancoE = Toolkit.getDefaultToolkit().getImage("Imagens/CarroBrancoE.jpg");
        public Image CarroVermelhoD = Toolkit.getDefaultToolkit().getImage("Imagens/CarroVermelhoD.jpg");
        public Image CarroVermelhoE = Toolkit.getDefaultToolkit().getImage("Imagens/CarroVermelhoE.jpg");
        public Image Smile = Toolkit.getDefaultToolkit().getImage("Imagens/Smile.jpg");
        public Image Tronco01 = Toolkit.getDefaultToolkit().getImage("Imagens/Tronco01.jpg");
        public Image Tronco02 = Toolkit.getDefaultToolkit().getImage("Imagens/Tronco02.jpg");
    /** FIM Carregando as imagens */
    
    public GerenciadorImagem(Frogger oFrogger, GraphicsConfiguration graficoConfiguracao) {        
        /** Carregando a Thread Principal*/
        this.oFrogger = oFrogger;
        this.graficoConfiguracao = graficoConfiguracao;
        
        this.setDaemon(true);
        
        /* Desenhando todos as Imagens */
            this.oFrogger.prepareImage(Sapo01, oFrogger);
            this.oFrogger.prepareImage(Sapo02, oFrogger);
            this.oFrogger.prepareImage(Sapo03, oFrogger);
            this.oFrogger.prepareImage(Sapo04, oFrogger);
            this.oFrogger.prepareImage(SapoMorto, oFrogger);
            this.oFrogger.prepareImage(Caminhao01, oFrogger);
            this.oFrogger.prepareImage(Caminhao02, oFrogger);
            this.oFrogger.prepareImage(Caminhao03, oFrogger);
            this.oFrogger.prepareImage(CarroAzulD, oFrogger);
            this.oFrogger.prepareImage(CarroAzulE, oFrogger);
            this.oFrogger.prepareImage(CarroVermelhoD, oFrogger);
            this.oFrogger.prepareImage(CarroVermelhoE, oFrogger);
            this.oFrogger.prepareImage(CarroBrancoD, oFrogger);
            this.oFrogger.prepareImage(CarroBrancoE, oFrogger);
            this.oFrogger.prepareImage(Tronco01, oFrogger);
            this.oFrogger.prepareImage(Tronco02, oFrogger);
            this.oFrogger.prepareImage(Smile, oFrogger);
        /** FIM do Carregamento das Imagens na Memoria */
            
        /** INICIO da Criacao das posicoes dos Smiles */
            this.retanguloSmile = new Rectangle[5];
            
            this.retanguloSmile[0] = new Rectangle(20, 70, 40, 20);
            this.retanguloSmile[1] = new Rectangle(100, 70, 40, 20);
            this.retanguloSmile[2] = new Rectangle(180, 70, 40, 20);
            this.retanguloSmile[3] = new Rectangle(260, 70, 40, 20);
            this.retanguloSmile[4] = new Rectangle(340, 70, 40, 20);
        /** FIM da Criacao das posicoes dos Smiles */
        
        /** Carregando o Objeto VolatileImage */
        this.imagemFundo = this.graficoConfiguracao.createCompatibleVolatileImage(400, 400);
        
        /** Criando a Imagem Background e o seu Manipulador */
        Graphics graficoFundo = this.imagemFundo.getGraphics();
        
        /** INICIO da Criacao do Senario */
        /** Desenhando o Fundo Preto */
        graficoFundo.setColor(Color.BLACK);
        graficoFundo.fillRect(0, 0, 400, 400);
        
        /** Desenhando o Fundo Verde */
        graficoFundo.setColor(Color.GREEN);
        graficoFundo.fillRect(15, 60, 370, 300);
        
        /** Desenhando o Lago */
        graficoFundo.setColor(Color.BLUE);
        graficoFundo.fillPolygon(lago);
        
        /** Desenhando as duas Calcadas */
        graficoFundo.setColor(Color.YELLOW);
        graficoFundo.fillRect(20, 210, 360, 25);
        graficoFundo.fillRect(20, 335, 360, 25);
        
        /** Desenhando a Rua */
        graficoFundo.setColor(Color.LIGHT_GRAY);
        graficoFundo.fillRect(20, 235, 360, 100);
        
        /** FIM da Criacao do Senario */
              
        /** INICIO da Criacao dos Objetos do Senario */
            this.objetos = new Objetos[22];
            
            /** Criando os Objetos */
            this.objetos[0] = new Objetos("Sapo01", this);
            this.objetos[1] = new Objetos("Tronco01", this);
            this.objetos[2] = new Objetos("Tronco01", this);
            this.objetos[3] = new Objetos("Tronco02", this);
            this.objetos[4] = new Objetos("Tronco02", this);
            this.objetos[5] = new Objetos("Tronco02", this);
            this.objetos[6] = new Objetos("Tronco01", this);
            this.objetos[7] = new Objetos("Tronco01", this);
            this.objetos[8] = new Objetos("Tronco01", this);
            this.objetos[9] = new Objetos("Caminhao02", this);
            this.objetos[10] = new Objetos("Caminhao01", this);
            this.objetos[11] = new Objetos("CarroAzulD", this);
            this.objetos[12] = new Objetos("CarroBrancoD", this);
            this.objetos[13] = new Objetos("CarroAzulD", this);
            this.objetos[14] = new Objetos("CarroVermelhoD", this);
            this.objetos[15] = new Objetos("CarroBrancoE", this);
            this.objetos[16] = new Objetos("CarroAzulD", this);
            
            this.objetos[17] = new Objetos("", this);
            this.objetos[18] = new Objetos("", this);
            this.objetos[19] = new Objetos("", this);
            this.objetos[20] = new Objetos("", this);
            this.objetos[21] = new Objetos("", this);
            
            /** Dedinindo as Posicoes */
            
            // Sapo
            this.objetos[0].setPosicao(new Rectangle(200, 335, 20, 20));
            
            // Os dois primeiros Troncos
            this.objetos[1].setPosicao(new Rectangle(40, 95, 120, 20));
            this.objetos[2].setPosicao(new Rectangle(280, 95, 120, 20));
            
            // Os Tres terceiros Troncos
            this.objetos[3].setPosicao(new Rectangle(20, 125, 60, 20));
            this.objetos[4].setPosicao(new Rectangle(160, 125, 60, 20));
            this.objetos[5].setPosicao(new Rectangle(300, 125, 60, 20));
            
            // Um Tronco na Linha Tres
            this.objetos[6].setPosicao(new Rectangle(180, 155, 120, 20));
            
            // Dois Troncos na Linha Quatro
            this.objetos[7].setPosicao(new Rectangle(60, 185, 120, 20));
            this.objetos[8].setPosicao(new Rectangle(300, 185, 120, 20));
            
            // Dois Caminhoes na Linha Um
            this.objetos[9].setPosicao(new Rectangle(60, 235, 60, 20));
            this.objetos[10].setPosicao(new Rectangle(260, 235, 60, 20));
            
            // Dois Carros na Linha Dois
            this.objetos[11].setPosicao(new Rectangle(100, 255, 25, 20));
            this.objetos[12].setPosicao(new Rectangle(260, 255, 25, 20));
            
            // Dois Carros na Linha Tres
            this.objetos[13].setPosicao(new Rectangle(60, 275, 25, 20));
            this.objetos[14].setPosicao(new Rectangle(300, 275, 25, 20));
            
            // Um Carro na Linha Quatro
            this.objetos[15].setPosicao(new Rectangle(180, 295, 25, 20));
            
            // Um Carro na Linha Cinco
            this.objetos[16].setPosicao(new Rectangle(280, 315, 25, 20));
        /** FIM da Criacao dos Objetos do Senario */
        
        /** INICIO da Especificacao da Direcao do Objeto */
            this.objetos[1].setDirecaoObjeto("Esquerda");
            this.objetos[2].setDirecaoObjeto("Esquerda");
            
            this.objetos[3].setDirecaoObjeto("Direita");
            this.objetos[4].setDirecaoObjeto("Direita");
            this.objetos[5].setDirecaoObjeto("Direita");
            
            this.objetos[6].setDirecaoObjeto("Esquerda");
            
            this.objetos[7].setDirecaoObjeto("Direita");
            this.objetos[8].setDirecaoObjeto("Direita");
            
            this.objetos[9].setDirecaoObjeto("Esquerda");
            this.objetos[10].setDirecaoObjeto("Esquerda");
            
            this.objetos[11].setDirecaoObjeto("Direita");
            this.objetos[12].setDirecaoObjeto("Direita");
            
            this.objetos[13].setDirecaoObjeto("Direita");
            this.objetos[14].setDirecaoObjeto("Direita");
            
            this.objetos[15].setDirecaoObjeto("Esquerda");
            
            this.objetos[16].setDirecaoObjeto("Direita");
        /** FIM da Especificacao da Direcao do Objeto */
        
        /** Visualizando a Janela */
        this.oFrogger.setVisible(true);
        
        /** Criando os componentes para uma Melhor Renderizacao do Frame */
        this.oFrogger.createBufferStrategy(2);
        this.memoriaEstrategia = this.oFrogger.getBufferStrategy();
        this.graficoEstrategia = this.memoriaEstrategia.getDrawGraphics();
        
        /** Iniciando a Thread */
        this.oFrogger.iniciarTimer();
        this.start();
    }
    
    /** Metodo Inicial da Thread Principal */
    public synchronized void run(){
        this.tempoEstimadoSistema = System.currentTimeMillis() + this.tempoEsperaTotal;
        do {
            /** Veridicando se o Sapo andou */
            if (this.movimentoSapo == false){
                /** Movimentar todos os Objetos */
                for (int contador = 1; contador < this.objetos.length; contador++){
                    /** Verificando a Direcao do Objeto */
                    if (this.objetos[contador].getDirecaoObjeto() == "Direita"){
                        /** Verificando Colisao com os Troncos */
                        if (this.objetos[contador].getColisaoMorte() == false){
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true && this.objetos[0].getTipoImagem() != "SapoMorto"){
                                /** Verificando se o SApo chegou ate o Canto da tela Direita */
                                if (this.objetos[0].getPosicao().getX() + this.objetos[0].getPosicao().getWidth() + 20 <= 380){
                                    this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX() + 20), (int) (this.objetos[0].getPosicao().getY()), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                                }
                            }
                            this.objetos[contador].setPosicao(new Rectangle((int) (this.objetos[contador].getPosicao().getX() + 20), (int) (this.objetos[contador].getPosicao().getY()), (int) (this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getHeight())));
                        /** Verificando colisao com os outros objetos */
                        } else{
                            this.objetos[contador].setPosicao(new Rectangle((int) (this.objetos[contador].getPosicao().getX() + 20), (int) (this.objetos[contador].getPosicao().getY()), (int) (this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getHeight())));
                            /** Verificando Colisao com os outros Objetos */
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true){
                                /** Verificando se o Tempo de volta nao Foi estimado */
                                if (this.tempoSapoMorto == 0){
                                    this.tempoSapoMorto = System.currentTimeMillis() + 3000;
                                    this.objetos[0].carregarImagem("SapoMorto");
                                    this.vidas--;
                                    this.oFrogger.pararTimer();
                                }
                            }
                            
                        }
                    } else if (this.objetos[contador].getDirecaoObjeto() == "Esquerda"){
                        /** Verificando Colisao com os Troncos */
                        if (this.objetos[contador].getColisaoMorte() == false){
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true && this.objetos[0].getTipoImagem() != "SapoMorto"){
                                /** Verificando se o Sapo chegou ate o canto da tela Esquerda */
                                if (this.objetos[0].getPosicao().getX() - 15 >= 20){
                                    this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX() - 20), (int) (this.objetos[0].getPosicao().getY()), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                                }
                            }
                            this.objetos[contador].setPosicao(new Rectangle((int) (this.objetos[contador].getPosicao().getX() - 20), (int) (this.objetos[contador].getPosicao().getY()), (int) (this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getHeight())));
                        /** Verificando colisao com os outros objetos */
                        } else{
                            this.objetos[contador].setPosicao(new Rectangle((int) (this.objetos[contador].getPosicao().getX() - 20), (int) (this.objetos[contador].getPosicao().getY()), (int) (this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getHeight())));
                            /** Verificando Colisao com os outros Objetos */
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true){
                                /** Verificando se o Tempo de volta nao Foi estimado */
                                if (this.tempoSapoMorto == 0){
                                    this.tempoSapoMorto = System.currentTimeMillis() + 3000;
                                    this.objetos[0].carregarImagem("SapoMorto");
                                    this.vidas--;
                                    this.oFrogger.pararTimer();
                                }
                            }                            
                        }                        
                    }
                }
                /** Verificando se houve alguma colicao nos Troncos quando os Objetos andaram */
                if (this.objetos[0].getPosicao().getY() < 215){
                    int contador = 1;
                    boolean colidiu = false;
                    do{
                        /** Verificando se o Objeto nao eh considerado perigoso para o Sapo */
                        if (this.objetos[contador].getColisaoMorte() == false && this.objetos[contador].getPosicao() != null){
                            /** Verificando se o Sapo e o Objeto estao se colidindo */
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true){
                                colidiu = true;
                                contador = this.objetos.length;
                            }
                        }
                        contador++;
                    } while (contador < this.objetos.length);
                    /** Verificando se o Tempo de volta nao Foi estimado */
                    if (this.tempoSapoMorto == 0 && colidiu == false){
                        this.tempoSapoMorto = System.currentTimeMillis() + 3000;
                        this.objetos[0].carregarImagem("SapoMorto");
                        this.vidas--;
                        this.oFrogger.pararTimer();
                    }
                }
                   
                /** Verificando o nivel de Dificuldade */
                if (this.levelJogo == 1){
                    this.tempoEsperaTotal = 1000;
                } else if (this.levelJogo == 2){
                    this.tempoEsperaTotal = 900;
                } else if (this.levelJogo == 3){
                    this.tempoEsperaTotal = 800;
                } else if (this.levelJogo == 4){
                    this.tempoEsperaTotal = 700;
                } else if (this.levelJogo == 5){
                    this.tempoEsperaTotal = 600;
                } else if (this.levelJogo == 6){
                    this.tempoEsperaTotal = 500;
                } else if (this.levelJogo == 7){
                    this.tempoEsperaTotal = 400;
                } else if (this.levelJogo == 8){
                    this.tempoEsperaTotal = 300;
                } else if (this.levelJogo == 9){
                    this.tempoEsperaTotal = 200;
                } else{
                    this.tempoEsperaTotal = 100;
                }
                
                /** Valorizando o Tempo de Espera */
                this.tempoEspera = this.tempoEsperaTotal;
                this.tempoEstimadoSistema = System.currentTimeMillis() + this.tempoEsperaTotal;
            /** Se o Sapo Andou */
            } else{
                /** Verificando se houve alguma colisao nos Veiculos quando o Sapo andou */
                if (this.objetos[0].getPosicao().getY() >= 215){
                    /** Verificando se houve alguma colicao no sapo Andar */
                    for(int contador = 1; contador < this.objetos.length; contador++){
                        /** Verificando se o Objeto eh considerado perigoso para o Sapo */
                        if (this.objetos[contador].getColisaoMorte() == true){
                            /** Verificando se o Sapo e o Objeto estao se colidindo */
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true){
                                /** Verificando se o Tempo de volta nao Foi estimado */
                                if (this.tempoSapoMorto == 0){
                                    this.tempoSapoMorto = System.currentTimeMillis() + 3000;
                                    this.objetos[0].carregarImagem("SapoMorto");
                                    this.vidas--;
                                    this.oFrogger.pararTimer();
                                }
                            }
                        }
                    }
                /** Verificando se houve alguma colicao nos Troncos quando o Sapo andou */
                } else {
                    int contador = 1;
                    boolean colidiu = false;
                    do{
                        /** Verificando se o Objeto nao eh considerado perigoso para o Sapo */
                        if (this.objetos[contador].getColisaoMorte() == false && this.objetos[contador].getPosicao() != null){
                            /** Verificando se o Sapo e o Objeto estao se colidindo */
                            if (this.objetos[contador].getPosicao().intersects(this.objetos[0].getPosicao()) == true){
                                colidiu = true;
                                contador = this.objetos.length;
                            }
                        }
                        contador++;
                    } while (contador < this.objetos.length);
                    
                    contador = 0;
                    /** Verificando se Houver alguma colicao nos pontos da Casinha do Sapo */
                    do{
                        /** Verifica se Houve Colicao com algum pontos com as Casinhas */
                        if (this.retanguloSmile[contador].intersects(this.objetos[0].getPosicao()) == true){
                            colidiu = true;
                            boolean smileExiste = false;
                            this.objetos[0].carregarImagem("Sapo01");
                            this.objetos[0].setPosicao(new Rectangle(200, 335, 20, 20));
                            
                            /** Verificando se o Smile ja Existe */
                            int contador2 = 0;
                            do{
                                if (this.objetos[contador2].getTipoImagem() == "Smile" && this.objetos[contador2].getPosicao() == this.retanguloSmile[contador]){
                                    smileExiste = true;
                                    
                                    /** Valorizando a Variavel para Sair do While */
                                    contador2 = this.objetos.length;
                                }
                                contador2++;
                            } while(contador2 < this.objetos.length);
                            
                            /** Se o Smile ainda nao Existe, Criar */
                            if (smileExiste == false){
                                this.totalSmile++;
                                int contador3 = 0;
                                /** Verificando o Total de Smiles preenchidos */
                                if (this.totalSmile < 5){
                                    do{
                                        /** Verificando se Ha alguma vaga para a Criacao do Objeto */
                                        if (this.objetos[contador3].getTipoImagem() == ""){
                                            this.objetos[contador3].carregarImagem("Smile");
                                            this.objetos[contador3].setPosicao(this.retanguloSmile[contador]);
                                            
                                            /** Valorizando a Variavel para Sair do While */
                                            contador3 = this.objetos.length;
                                        }
                                        contador3++;
                                    } while(contador3 < this.objetos.length);
                                /** Se totalSmiles maior q 5, Passar para o proximo Nivel */
                                } else{
                                    this.levelJogo++;
                                    this.totalSmile = 0;
                                    /** Zerando todos os Smiles */
                                    for(int contador4 = 1; contador4 < this.objetos.length; contador4++){
                                        /** Verificando o Tipo de Objeto */
                                        if (this.objetos[contador4].getTipoImagem() == "Smile"){
                                            this.objetos[contador4].carregarImagem("");
                                        }
                                    }
                                }
                            }
                            
                            /** Valorizando a Variavel para Sair do While */
                            contador = this.retanguloSmile.length;
                            
                            this.oFrogger.iniciarTimer();
                        }
                        contador++;
                    } while (contador < this.retanguloSmile.length);
                    
                    /** Verificando se o Tempo de volta nao Foi estimado */
                    if (this.tempoSapoMorto == 0 && colidiu == false){
                        this.tempoSapoMorto = System.currentTimeMillis() + 3000;
                        this.objetos[0].carregarImagem("SapoMorto");
                        this.vidas--;
                        this.oFrogger.pararTimer();
                    }
                }
            }
           
            /** INICIO da Renderizacao da Imagem */ 
                /** Desenhando o Senario */
                this.graficoEstrategia.drawImage(this.imagemFundo, 0, 0, null);
                
                /** Desenhando os Objetos do Nivel 1 */
                for(int contador = 0; contador < this.objetos.length; contador++){
                    if (this.objetos[contador].getNivelVisibilidade() == 1){
                        this.graficoEstrategia.drawImage(this.objetos[contador].retornaImagem(), (int) (this.objetos[contador].getPosicao().getX()), (int) (this.objetos[contador].getPosicao().getY()),(int) (this.objetos[contador].getPosicao().getWidth()),(int) (this.objetos[contador].getPosicao().getHeight()), null);
                    }
                }
                
                /** Desenhando os Objetos do Nivel 2 */
                for(int contador = 0; contador < this.objetos.length; contador++){
                    if (this.objetos[contador].getNivelVisibilidade() == 2){
                        this.graficoEstrategia.drawImage(this.objetos[contador].retornaImagem(), (int) (this.objetos[contador].getPosicao().getX()), (int) (this.objetos[contador].getPosicao().getY()),(int) (this.objetos[contador].getPosicao().getWidth()),(int) (this.objetos[contador].getPosicao().getHeight()), null);
                    }
                }
                
                /** Desenhando os Objetos do Nivel 3 */
                for(int contador = 0; contador < this.objetos.length; contador++){
                    if (this.objetos[contador].getNivelVisibilidade() == 3){
                        this.graficoEstrategia.drawImage(this.objetos[contador].retornaImagem(), (int) (this.objetos[contador].getPosicao().getX()), (int) (this.objetos[contador].getPosicao().getY()),(int) (this.objetos[contador].getPosicao().getWidth()),(int) (this.objetos[contador].getPosicao().getHeight()), null);
                    }
                }
            /** FIM da Renderizacao da Imagem */
            
            /** INICIO da Finalizacao da Criacao da Imagem */
                /** Acertando as Bordas da Imagem */
                this.graficoEstrategia.setColor(Color.BLACK);
                this.graficoEstrategia.fillRect(385, 60, 30, 360);
                this.graficoEstrategia.fillRect(0, 60, 20, 300);
                this.graficoEstrategia.setColor(Color.GREEN);
                this.graficoEstrategia.fillRect(380, 70, 5, 290);
                this.graficoEstrategia.fillRect(15, 60, 5, 300);
                
                /** Mostrando o Nome do Criador */
                this.graficoEstrategia.drawString("Criado por Rennan Stefan Boni -=- rennanboni@yahoo.com.br", 15, 35);
                
                /** Mostrando o Total de Vidas */
                this.graficoEstrategia.drawString("Vidas: " + this.vidas, 20, 380);
                
                /** Mostrando o Nivel Corrente do Jogo */
                this.graficoEstrategia.drawString("Nivel: " + this.levelJogo, 335, 55);
                
                /** Mostrando o Tempo Restante para a Travessia */
                this.graficoEstrategia.drawString("Tempo : " + this.oFrogger.getTempoRestante(), 300, 380);
                
                /** Exibindo mensagem para Reniciar o Jogo */
                if (this.vidas <= 0){
                    this.graficoEstrategia.setColor(Color.BLACK);
                    this.graficoEstrategia.drawString("..::Pressione a tecla ENTER para jogar novamente::..", 60, 275);
                    this.oFrogger.pararTimer();
                }
                
                if (this.levelJogo == 11){
                    Font fonteTemporaria = this.graficoEstrategia.getFont();
                    this.graficoEstrategia.setFont(new Font(null, java.awt.Font.BOLD, 20));
                    
                    int sorteio = (int) (Math.random() * 4 + 1);
                    if (sorteio == 1){
                        this.graficoEstrategia.setColor(Color.WHITE);
                    } else if (sorteio == 2){
                        this.graficoEstrategia.setColor(Color.BLACK);
                    } else if (sorteio == 3){
                        this.graficoEstrategia.setColor(Color.RED);
                    } else if (sorteio == 4){
                        this.graficoEstrategia.setColor(Color.GREEN);
                    }
                    
                    this.graficoEstrategia.drawString("PARABENS !!!", 150, 150);
                    
                    this.graficoEstrategia.setFont(new Font(null, java.awt.Font.BOLD, 15));
                    this.graficoEstrategia.setColor(Color.RED);
                    this.graficoEstrategia.drawString("                    FIM DE JOGO", 50, 220);
                    
                    this.graficoEstrategia.setColor(Color.BLACK);
                    this.graficoEstrategia.drawString("                       Creditos", 50, 240);
                    
                    this.graficoEstrategia.setColor(new java.awt.Color(0, 150, 0));
                    this.graficoEstrategia.drawString("Planejador:         Rennan Stefan Boni", 50, 260);
                    this.graficoEstrategia.drawString("Programador:     Rennan Stefan Boni", 50, 280);
                    this.graficoEstrategia.drawString("Desenvolvedor:  Rennan Stefan Boni", 50, 300);
                    this.graficoEstrategia.drawString("Email: rennanboni@yahoo.com.br", 50, 320);
                    
                    this.graficoEstrategia.setFont(fonteTemporaria);
                    this.oFrogger.pararTimer();
                }
                
                /** Mostrando o Total de Tempo Restante */
                //this.graficoEstrategia.drawString("Tempo: " + this.tempoRestante, 300,380);
            /** FIM da Finalizacao da Criacao da Imagem */
            
            /** Verificando se Algum Objeto nao esta mais sendo Visualizado */
            for (int contador = 1; contador < this.objetos.length; contador++){
                /** Verificando qual e a Direcao do Objeto */
                if (this.objetos[contador].getDirecaoObjeto() == "Direita"){
                    /** Verificando se o Objeto nao esta mais Visivel */
                    if (this.objetos[contador].getPosicao().getX() > 380){
                        this.objetos[contador].setPosicao(new Rectangle((int) (20 - this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getY()), (int) (this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getHeight())));
                        /** Verificando o Tipo de Objeto para a possivel troca de Imagem */
                        if (this.objetos[contador].getTrocaImagem() == true){
                            /** Sorteando a Imagem para o Objeto tipo Caminhao */
                            if (this.objetos[contador].getTipoImagem() == "Caminhao01" || this.objetos[contador].getTipoImagem() == "Caminhao02" || this.objetos[contador].getTipoImagem() == "Caminhao03"){
                                int sorteio = (int) ((Math.random() * 3) + 1);
                                if (sorteio == 1){
                                    this.objetos[contador].carregarImagem("Caminhao01");
                                } else if (sorteio == 2){
                                    this.objetos[contador].carregarImagem("Caminhao02");
                                } else if (sorteio == 3){
                                    this.objetos[contador].carregarImagem("Caminhao03");
                                }
                            /** Sorteando a Imagem para o Objeto tipo Carro */
                            } else {
                                int sorteio = (int) ((Math.random() * 3) + 1);
                                if (sorteio == 1){
                                    this.objetos[contador].carregarImagem("CarroBrancoD");
                                } else if (sorteio == 2){
                                    this.objetos[contador].carregarImagem("CarroAzulD");
                                } else if (sorteio == 3){
                                    this.objetos[contador].carregarImagem("CarroVermelhoD");
                                }
                            }
                        }
                    }
                            
                /** Verificando a Direcao do Objeto */
                } else if (this.objetos[contador].getDirecaoObjeto() == "Esquerda"){
                    /** Verificando se o Objeto nao esta mais Visivel */
                    if (this.objetos[contador].getPosicao().getX() + this.objetos[contador].getPosicao().getWidth() < 20){
                        this.objetos[contador].setPosicao(new Rectangle(380, (int) (this.objetos[contador].getPosicao().getY()), (int) (this.objetos[contador].getPosicao().getWidth()), (int) (this.objetos[contador].getPosicao().getHeight())));
                        /** Verificando o Tipo de Objeto para a possivel troca de Imagem */
                        if (this.objetos[contador].getTrocaImagem() == true){
                            /** Sorteando a Imagem para o Objeto do Tipo Caminhao */
                            if (this.objetos[contador].getTipoImagem() == "Caminhao01" || this.objetos[contador].getTipoImagem() == "Caminhao02" || this.objetos[contador].getTipoImagem() == "Caminhao03"){
                                int sorteio = (int) ((Math.random() * 3) + 1);
                                if (sorteio == 1){
                                    this.objetos[contador].carregarImagem("Caminhao01");
                                } else if (sorteio == 2){
                                    this.objetos[contador].carregarImagem("Caminhao02");
                                } else if (sorteio == 3){
                                    this.objetos[contador].carregarImagem("Caminhao03");
                                }
                            /** Sorteando a Imagem para o Objeto Tipo Carro */
                            } else {
                                int sorteio = (int) ((Math.random() * 3) + 1);
                                if (sorteio == 1){
                                    this.objetos[contador].carregarImagem("CarroBrancoE");
                                } else if (sorteio == 2){
                                    this.objetos[contador].carregarImagem("CarroAzulE");
                                } else if (sorteio == 3){
                                    this.objetos[contador].carregarImagem("CarroVermelhoE");
                                }
                            }
                        }
                    }
                }
            }
            
            /** Verificando o Tempo depois do Sapo Morto */
            if (this.objetos[0].getTipoImagem() == "SapoMorto"){
                /** Verificando o Tempo de Espera depois de Morto */
                if (this.tempoSapoMorto < System.currentTimeMillis() && this.vidas > 0){
                    this.tempoSapoMorto = 0;
                    this.objetos[0].carregarImagem("Sapo01");
                    this.objetos[0].setPosicao(new Rectangle(200, 335, 20, 20));
                    this.oFrogger.iniciarTimer();
                }
            }
                
            /** Mostrando a Imagem */
            this.memoriaEstrategia.show(); 
            
            /** Parando a Thread por um Tempo determinado */
            try{
                /** Se o Sapo andou entao, calcular o tempo de Espera */
                if (this.movimentoSapo == true){
                    /** Se o Tempo de Espera nao completou o ciclo verificar o tempo Restante */
                    this.tempoEspera = this.tempoEstimadoSistema - System.currentTimeMillis();
                }
                
                /** Mudando o Valor do Andar do Sapo */
                this.movimentoSapo = false;
                
                if (this.tempoEspera > 0){
                    this.wait(this.tempoEspera);
                }
            } catch (InterruptedException Erro){}
        } while (true);
    }
    
    /** Metodo que liberar a Thread */
    public synchronized void liberarThread() {
        try {
            if (this.movimentoSapo == false){
                this.movimentoSapo = true;
                this.notify();
            }
        } catch (Exception erro){}
    }
    
    public synchronized void entradaEvento(java.awt.event.KeyEvent Evento){
        /** Verificando a Tipo de Tecla Acionada */
        if (this.objetos[0].getTipoImagem() != "SapoMorto" && this.levelJogo < 11){
            /** Se a tecla for Cima, Processar Evento */
            if (Evento.getKeyCode() == Evento.VK_UP){
                if (this.objetos[0].getPosicao().getY() + 20 > 60){
                    /** Verificando se e Nescessario carregar o Imagem */
                    if (this.objetos[0].getTipoImagem() != "Sapo01"){
                        this.objetos[0].carregarImagem("Sapo01");    
                    }
                    if (this.objetos[0].getPosicao().getY() <= 95){
                        this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX()), (int) (this.objetos[0].getPosicao().getY() - 25), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    } else if (this.objetos[0].getPosicao().getY() <= 215){
                        this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX()), (int) (this.objetos[0].getPosicao().getY() - 30), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    } else{
                        this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX()), (int) (this.objetos[0].getPosicao().getY() - 20), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    }
                    this.movimentoSapo = true;    
                    this.notify();
                }
                /** Se a tecla for Baixo, Processar Evento */
            } else if (Evento.getKeyCode() == Evento.VK_DOWN){
                if (this.objetos[0].getPosicao().getY() + this.objetos[0].getPosicao().getHeight() + 20 < 360){
                    /** Verificando se e Nescessario carregar o Imagem */
                    if (this.objetos[0].getTipoImagem() != "Sapo03"){
                        this.objetos[0].carregarImagem("Sapo03");
                    }
                     if (this.objetos[0].getPosicao().getY() < 215){
                        this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX()), (int) (this.objetos[0].getPosicao().getY() + 30), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    } else{
                        this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX()), (int) (this.objetos[0].getPosicao().getY() + 20), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    }
                    this.movimentoSapo = true;
                    this.notify();
                }
                /** Se a tecla for Direita, Processar Evento */
            } else if (Evento.getKeyCode() == Evento.VK_RIGHT){
                if (this.objetos[0].getPosicao().getX() + this.objetos[0].getPosicao().getWidth() + 20 <= 380){
                    /** Verificando se e Nescessario carregar o Imagem */
                    if (this.objetos[0].getTipoImagem() != "Sapo02"){
                        this.objetos[0].carregarImagem("Sapo02");
                    }
                    this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX() + 20), (int) (this.objetos[0].getPosicao().getY()), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    this.movimentoSapo = true;
                    this.notify();
                }
                /** Se a tecla for Esquerda, Processar Evento */
            } else if (Evento.getKeyCode() == Evento.VK_LEFT){
                /** Verificando se o Sapo nao vai sair da tela */
                if (this.objetos[0].getPosicao().getX() - 15 >= 20){
                    /** Verificando se e Nescessario carregar o Imagem */
                    if (this.objetos[0].getTipoImagem() != "Sapo04"){
                        this.objetos[0].carregarImagem("Sapo04");    
                    }
                    this.objetos[0].setPosicao(new Rectangle ((int) (this.objetos[0].getPosicao().getX() - 20), (int) (this.objetos[0].getPosicao().getY()), (int) (this.objetos[0].getPosicao().getWidth()), (int) (this.objetos[0].getPosicao().getHeight())));
                    this.movimentoSapo = true;
                    this.notify();
                }
            }
        /** Verificando se o Sapo Esta como Morto */
        } else{
            /** Se as Vidas Acabaram e foi Precionado ENTER, Reiniciar o Jogo */
            if (this.vidas <= 0 && Evento.getKeyCode() == Evento.VK_ENTER){
                this.vidas = 3;
                /** Limpando os Smiles */
                for (int contador = 1; contador < this.objetos.length; contador++){
                    if (this.objetos[contador].getTipoImagem() == "Smile"){
                        this.objetos[contador].carregarImagem("");
                    }
                }
                /** Posicao Inicial do Sapo */
                this.totalSmile = 0;
                this.levelJogo = 1;
                this.tempoSapoMorto = 0;
                this.objetos[0].carregarImagem("Sapo01");
                this.objetos[0].setPosicao(new Rectangle(200, 335, 20, 20));
                this.oFrogger.iniciarTimer();
            }
        }
    }
    
    /** Metodo que Indica que o Tempo de Atravessia acabou */
    public void tempoEsgotado(){
        this.tempoSapoMorto = System.currentTimeMillis() + 3000;
        this.objetos[0].carregarImagem("SapoMorto");
        this.vidas--;
    }
}

class Objetos {
    
    /** Variavel que carrega a Imagem do Objeto */
    private Image imagem = null;
    
    /** Variavel que carrega a posicao X, Y, Comprimento e Altura do Objeto */
    private Rectangle posicao = null;
    
    /** Variavel que indica qual direcao o Objeto esta indo */
    private String direcaoObjeto = null;
    
    /** Varivel que indica qual eh a Imagem q o objeto esta representando */
    private String tipoImagem = null;
    
    /** Variavel para a Manipulacao da Thread Gerenciador de Imagem */
    private GerenciadorImagem oGerenciadorImagem;
    
    /** Variavel que indica em qual nivel de Visibilidade o Objeto pertence 
     * 1 = Sao os Objetos que ficam a Baixo de Todos (TRONCOS)
     * 2 = Sao os Objetos que ficam acima do 1 e Abaixo do Dois (SAPO)
     * 3 = Sao os Objetos que ficam acima de Todos os Outros Objetos (Veiculos
     */
    private int nivelVisibilidade = 0;
    
    /** Variavel que indica se o Objeto comparado eh para considerar a morte para o sapo
     * caso aconteca uma colisao
     */
    private boolean colisaoMorte = false;
    
    /** Variavel que indica se o Objeto pode ou nao trocar de Imagem */
    private boolean trocaImagem = false;
    
    public Objetos(String imagemTexto, GerenciadorImagem oGerenciadorImagem){
        this.oGerenciadorImagem = oGerenciadorImagem;
        this.carregarImagem(imagemTexto);
    }
    
    public void carregarImagem(String imagemTexto){
        /** Carregando o Tipo de Imagem */
        this.tipoImagem = imagemTexto;
        
        /** Carregando a Imagem definida */
        if (imagemTexto == "Sapo01"){
            this.imagem = this.oGerenciadorImagem.Sapo01;
            this.nivelVisibilidade = 2;
        } else if (imagemTexto == "Sapo02"){
            this.imagem = this.oGerenciadorImagem.Sapo02;
            this.nivelVisibilidade = 2;
        } else if (imagemTexto == "Sapo03"){
            this.imagem = this.oGerenciadorImagem.Sapo03;
            this.nivelVisibilidade = 2;
        } else if (imagemTexto == "Sapo04"){
            this.imagem = this.oGerenciadorImagem.Sapo04;
            this.nivelVisibilidade = 2;
        } else if (imagemTexto == "SapoMorto"){
            this.imagem = this.oGerenciadorImagem.SapoMorto;
            this.nivelVisibilidade = 2;
        } else if (imagemTexto == "Caminhao01"){
            this.imagem = this.oGerenciadorImagem.Caminhao01;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "Caminhao02"){
            this.imagem = this.oGerenciadorImagem.Caminhao02;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "Caminhao03"){
            this.imagem = this.oGerenciadorImagem.Caminhao03;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "CarroAzulE"){
            this.imagem = this.oGerenciadorImagem.CarroAzulE;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "CarroAzulD"){
            this.imagem = this.oGerenciadorImagem.CarroAzulD;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "CarroBrancoE"){
            this.imagem = this.oGerenciadorImagem.CarroBrancoE;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "CarroBrancoD"){
            this.imagem = this.oGerenciadorImagem.CarroBrancoD;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "CarroVermelhoE"){
            this.imagem = this.oGerenciadorImagem.CarroVermelhoE;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "CarroVermelhoD"){
            this.imagem = this.oGerenciadorImagem.CarroVermelhoD;
            this.nivelVisibilidade = 3;
            this.colisaoMorte = true;
            this.trocaImagem = true;
        } else if (imagemTexto == "Tronco01"){
            this.imagem = this.oGerenciadorImagem.Tronco01;
            this.nivelVisibilidade = 1;
        } else if (imagemTexto == "Tronco02"){
            this.imagem = this.oGerenciadorImagem.Tronco02;
            this.nivelVisibilidade = 1;
        } else if (imagemTexto == "Smile"){
            this.imagem = this.oGerenciadorImagem.Smile;
            this.nivelVisibilidade = 3;
        } else if (imagemTexto == ""){
            this.imagem = null;
        }
    }
    
    /** Retorna a Imagem Espessificada para este Objeto */
    public Image retornaImagem(){
        return this.imagem;
    }
    
    /** Retorna uma String Contendo qual direcao o Objeto se Citua */
    public String getDirecaoObjeto(){
        return this.direcaoObjeto;
    }
    
    /** Especifica a Direcao que o Objeto se Citua */
    public void setDirecaoObjeto(String direcaoObjeto){
        this.direcaoObjeto = direcaoObjeto;
    }
    
    /** Retorna as posicoes X, Y, Width e Height ocupada por este Objeto */
    public Rectangle getPosicao(){
        return this.posicao;
    }
    
    /** Especifica as Propriedades X, Y, Width e Height para o Objeto */
    public void setPosicao(Rectangle posicao){
        this.posicao = posicao;
    }
    
    /** Retorna uma String que especifica o Tipo de Imagem ja Carregada */
    public String getTipoImagem(){
        return this.tipoImagem;
    }
    
    /* Retorna um Inteiro que especifica o nivel de Altura dos Objetos **/
    public int getNivelVisibilidade(){
        return this.nivelVisibilidade;
    }
    
    /** Retorna um Valor Boleano que especifica se o Objeto aceita trocar de Imagem */
    public boolean getTrocaImagem(){
        return this.trocaImagem;
    }
    
    /** Retorna um Valor Boleano que especifica se o Objeto caso tenha uma colisao 
     * deve considerar como Morte ao Sapo
     */
    public boolean getColisaoMorte(){
        return this.colisaoMorte;
    }
}